﻿using Mimas.Core.Current;
using Mimas.Framework.Shared.Data.CriteriaObjects;
using Mimas.Framework.Shared.Data.DataTransferObjects;
using Mimas.Framework.Shared.Services.AdminManagementServices;
using Mimas.Framework.Shared.Services.AdvManagementServices;
using Mimas.Framework.Shared.Services.CommonManagementServices;
using Mimas.Framework.Shared.Services.PublicServices;
using Mimas.Framework.Shared.Services.SecurityServices;
using Mimas.Framework.Shared.Services.UserManagementServices;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace Mimas.Enterprise.UI
{
  public class MimasControllerBase : Controller
  {
    private string BaseErrorPage = "~/Views/Shared/Error.cshtml";

    public static void ApplicationStart()
    {
      if (Constants.AccessLists == null || !Constants.AccessLists.Any()) svcConstantManager.SearchAccessLists(new AccessListCO());
      if (Constants.Countries == null || !Constants.Countries.Any()) svcConstantManager.SearchCountries(new CountryCO());
      if (Constants.Lookuplists == null || !Constants.Lookuplists.Any()) svcConstantManager.SearchLookupLists(new LookupListCO());
      if (Constants.MenuItems == null || !Constants.MenuItems.Any()) svcConstantManager.SearchMenus(new MenuItemCO());
      if (Constants.Towns == null || !Constants.Towns.Any()) svcConstantManager.SearchTowns(new TownCO());
    }

    #region Services

    public static IAdvManagementService svcAdvManagementService = new AdvManagementService();
    public static ICommonManagementService svcCommonManagementService = new CommonManagementService();
    public static ISecurityService svcSecurityService = new SecurityService();
    public static IUserManager svcUserManager = new UserManager();
    public static IConstantManager svcConstantManager = new ConstantManager();
    public static IFileManager svcFileManager = new FileManager();
    public static IPublicService svcPublicService = new PublicService();

    #endregion Services

    protected override void OnException(ExceptionContext filterContext)
    {
      try
      {
        if (filterContext.Exception == null)
        {
          base.OnException(filterContext);
        }
        else
        {
          string controllerName = filterContext.RequestContext.RouteData.Values["controller"].ToString();
          MethodInfo info = (from f in new StackTrace(filterContext.Exception).GetFrames()
                             where f.GetMethod() is MethodInfo
                             select f.GetMethod() as MethodInfo).FirstOrDefault<MethodInfo>(m => (m.IsPublic && typeof(IController).IsAssignableFrom(m.DeclaringType)) && ((m.ReturnType == typeof(ActionResult)) || m.ReturnType.IsSubclassOf(typeof(ActionResult))));
          Type type = (info == null) ? null : info.ReturnType;
          object[] source = (info == null) ? null : info.GetCustomAttributes(false);
          bool flag = (source != null) && source.Any<object>(attr => (attr.GetType() == typeof(HandleErrorAttribute)));
          if (((type != null) && (type == typeof(JsonResult))) && true)
          {
            filterContext.ExceptionHandled = true;
            filterContext.Result = this.HandleExceptionAsJsonResult(filterContext.Exception, false);
          }
          else if (((type != null) && (type == typeof(ActionResult))) && flag)
          {
            filterContext.ExceptionHandled = true;
            HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, info.Name);
            filterContext.Result = base.View(BaseErrorPage, model);
          }
          else
          {
            base.OnException(filterContext);
          }
        }
      }
      catch
      {
        base.OnException(filterContext);
      }
    }

    [NonAction]
    public JsonResult HandleExceptionAsJsonResult(Exception ex, bool isWarning = false)
    {
      base.Response.StatusCode = 500;
      base.Response.TrySkipIisCustomErrors = true;
      base.Response.ContentType = "application/json; charset=utf-8";
      if (ex == null)
      {
        return new JsonResult { Data = new { errorType = "error", errorMessage = "Unknown Error : Exception argument 'ex' is null.", exceptionType = "Exception" }, ContentEncoding = Encoding.UTF8 };
      }
      bool flag = ((isWarning || (ex is ArgumentException)) || ((ex is ArgumentNullException) || (ex is ArgumentOutOfRangeException))) || (ex is FormatException);
      string str = ex.Message + ((ex.InnerException == null) ? string.Empty : (" || " + ex.InnerException.Message));
      var type = new
      {
        errorType = flag ? "warning" : "error",
        errorMessage = str,
        exceptionType = ex.GetType().Name
      };
      return new JsonResult { Data = type, ContentEncoding = Encoding.UTF8, MaxJsonLength = 0x7fffffff, RecursionLimit = 100, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
    }

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
      base.OnAuthorization(filterContext);
      //filterContext.HttpContext.Request.Url
      //giriş yetkisi kontrol edilecek.

    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
      ApplicationStart();
      base.OnActionExecuting(filterContext);
      this.InitializeCulture();
    }

    protected virtual void InitializeCulture()
    {
      GetCultureInfo();
    }

    public void SetCultureInfo(CultureInfo culture)
    {
      Culture.CurrentCulture = culture;
    }

    public CultureInfo GetCultureInfo()
    {
      return Culture.CurrentCulture;
    }
  }
}
